package com.brillilab.starter.controller.aio.system;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.openservices.shade.org.apache.commons.lang3.StringUtils;
import com.brillilab.common.constant.ResultEnum;
import com.brillilab.common.constant.SystemConfigConstant;
import com.brillilab.common.entity.ResponseVo;
import com.brillilab.common.redis.RedisCache;
import com.brillilab.common.utils.DateUtil;
import com.brillilab.common.utils.EmailSendUtil;
import com.brillilab.common.utils.TimeUtil;
import com.brillilab.domain.enums.lab.LabMemberEnum;
import com.brillilab.domain.enums.lab.LabMemberPowerEnum;
import com.brillilab.domain.enums.lab.LabMemberPowerEnum.Power;
import com.brillilab.domain.enums.lab.UserAuditInviteStateEnum;
import com.brillilab.domain.enums.lab.UserInviteAuditStateEnum;
import com.brillilab.domain.enums.system.ClientVersionTypeEnum;
import com.brillilab.domain.po.lab.LabMember;
import com.brillilab.domain.po.system.ClientVersion;
import com.brillilab.domain.po.system.Company;
import com.brillilab.domain.po.system.Dict;
import com.brillilab.domain.po.system.SystemConfig;
import com.brillilab.domain.po.user.UserInviteAudit;
import com.brillilab.domain.po.user.Users;
import com.brillilab.domain.vo.lab.LabDutyVo;
import com.brillilab.domain.vo.system.DictGroupVo;
import com.brillilab.domain.vo.system.UserDutyVo;
import com.brillilab.domain.vo.user.UserInfoVo;
import com.brillilab.service.core.email.impl.EmailServiceImpl;
import com.brillilab.service.core.kit.IReagentTypeService;
import com.brillilab.service.core.lab.ILabMemberService;
import com.brillilab.service.core.system.IClientVersionService;
import com.brillilab.service.core.system.ICompanyService;
import com.brillilab.service.core.system.IDictService;
import com.brillilab.service.core.system.ISystemConfigService;
import com.brillilab.service.core.user.IUserInviteAuditService;
import com.brillilab.service.core.user.IUsersService;
import com.brillilab.service.logic.lab.LabApplyLogic;
import com.brillilab.service.logic.message.MessageLogic;
import com.brillilab.service.logic.user.UserInviteAuditLogic;
import com.brillilab.service.logic.user.UsersLogic;
import com.brillilab.starter.constant.StarterConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 字典表
 *
 * @author lj
 */
@RestController
@RequestMapping("/api/system")
@Slf4j
public class SystemController {
    @Resource
    private UsersLogic usersLogic;
    @Resource
    private IUsersService usersService;
    @Resource
    private IDictService dictService;
    @Resource
    private ICompanyService companyService;
    @Resource
    private IReagentTypeService reagentTypeService;
    @Resource
    private ILabMemberService labMemberService;
    @Resource
    private IClientVersionService clientVersionService;
    @Resource
    private UserInviteAuditLogic userInviteAuditLogic;
    @Resource
    private EmailServiceImpl emailService;
    @Resource
    private ISystemConfigService systemConfigService;
    @Resource
    private IUserInviteAuditService userInviteAuditService;
    @Resource
    private LabApplyLogic labApplyLogic;
    @Resource
    private MessageLogic messageLogic;
    @Resource
    private RedisCache redisCache;

    /**
     * 获取单位
     *
     * @return
     */
    @RequestMapping(value = "/unit", method = RequestMethod.GET)
    public ResponseVo getUnit() {
        List<DictGroupVo> groupVoList = new ArrayList<>();
        Map<String, List<Dict>> unitMap = dictService.getUnit();
        for (String groupName : unitMap.keySet()) {
            DictGroupVo groupVo = new DictGroupVo();
            groupVo.setGroupName(groupName);
            List<Dict> list = unitMap.get(groupName);
            if (list != null && list.size() > 0)
                groupVo.setType(list.get(0).getType());
            groupVo.setDictList(list);
            groupVoList.add(groupVo);
        }

        return ResponseVo.success(groupVoList);
    }

    /**
     * 获取温区
     *
     * @return
     */
    @RequestMapping(value = "/zone", method = RequestMethod.GET)
    public ResponseVo getZone() {
        return ResponseVo.success(dictService.getZone());
    }

    /**
     * 获取职称（老）
     *
     * @return
     */
    @RequestMapping(value = "/duty", method = RequestMethod.GET)
    public ResponseVo getTitle() {
        return ResponseVo.success(dictService.getDuty());
    }

    /**
     * 获取职务列表
     *
     * @return
     */
    @GetMapping("/getDutyList")
    public ResponseVo getDutyList() {
        Map<Integer, String> map = dictService.getUserDutyMap();
        LabDutyVo labDutyVo = new LabDutyVo();

        if(redisCache.getObj("dutyList")!=null){
            log.info("职务列表-redis");
            labDutyVo=(LabDutyVo)redisCache.getObj("dutyList");
        }else {
            List<UserDutyVo> userDutyList = new ArrayList<>();
            List<UserDutyVo> doctorList = new ArrayList<>();
            List<UserDutyVo> masterList = new ArrayList<>();
            map.forEach((code, name) -> {
                UserDutyVo userDutyVo = new UserDutyVo();
                userDutyVo.setCode(code);
                userDutyVo.setName(name);
                if (code >= 100 && code < 200) {
                    userDutyList.add(userDutyVo);
                } else if (code >= 200 && code < 300) {
                    userDutyVo.setName(name.substring(2));
                    doctorList.add(userDutyVo);
                } else if (code >= 300 && code < 400) {
                    userDutyVo.setName(name.substring(2));
                    masterList.add(userDutyVo);
                }
            });
            labDutyVo.setUserDutyList(userDutyList);
            labDutyVo.setDoctorList(doctorList);
            labDutyVo.setMasterList(masterList);

            log.info("职务列表-mysql");
            redisCache.set("dutyList",labDutyVo);
        }

        return ResponseVo.success(labDutyVo);
    }

    /**
     * 获取职称
     *
     * @return
     */
    @RequestMapping(value = "/duties", method = RequestMethod.GET)
    public ResponseVo getDuty() {
        Map<Integer, String> map = dictService.getUserDutyMap();
        LabDutyVo labDutyVo = new LabDutyVo();
        List<UserDutyVo> userDutyList = new ArrayList<>();
        List<UserDutyVo> doctorList = new ArrayList<>();
        List<UserDutyVo> masterList = new ArrayList<>();
        map.forEach((code, name) -> {
            UserDutyVo userDutyVo = new UserDutyVo();
            userDutyVo.setCode(code);
            userDutyVo.setName(name);
            if (code >= 100 && code < 200) {
                userDutyList.add(userDutyVo);
            } else if (code >= 200 && code < 300) {
                userDutyVo.setName(name.substring(2));
                doctorList.add(userDutyVo);
            } else if (code >= 300 && code < 400) {
                userDutyVo.setName(name.substring(2));
                masterList.add(userDutyVo);
            }
        });
        labDutyVo.setUserDutyList(userDutyList);
        labDutyVo.setDoctorList(doctorList);
        labDutyVo.setMasterList(masterList);
        return ResponseVo.success(labDutyVo);
    }


    /**
     * 获取公司
     *
     * @return
     */
    @RequestMapping(value = "/company", method = RequestMethod.GET)
    public ResponseVo getCompany() {
        return ResponseVo.success(companyService.getCompanyGroup());

    }

    /**
     * 获取试剂类型
     *
     * @return
     */
    @RequestMapping(value = "/reagentType", method = RequestMethod.GET)
    public ResponseVo getReagentType(@RequestHeader(name = StarterConstant.TOKEN) String token) {
        UserInfoVo urs = usersLogic.getUserByToken(token);
        return ResponseVo.success(reagentTypeService.getTypeList(urs.getLabId(), urs.getLabMemberId()));
    }

    /**
     * 获取权限
     *
     * @return
     */
    @RequestMapping(value = "/power", method = RequestMethod.GET)
    public ResponseVo getPower(@RequestHeader(value = StarterConstant.TOKEN) String token) {
        List<Dict> list = new ArrayList<>();
        Power[] powers = LabMemberPowerEnum.Power.values();
        for (Power power : powers) {
            Dict dict = new Dict();
            dict.setName(power.getKey());
            dict.setType(power.getValue());
            list.add(dict);
        }

        list = list.stream().filter(e -> !e.getName().equals(Power.RESEARCH_GROUP_MANAGE.getKey())).collect(Collectors.toList());
        //团队管理权限只有PI能赋予
//		UserInfoVo userInfo=usersLogic.getUserByToken(token);
//		if(!labMemberPowerService.isOwner(userInfo.getLabId(),userInfo.getLabMemberId())){
//			list = list.stream().filter(e -> !e.getName().equals(Power.RESEARCH_GROUP_MANAGE.getKey())).collect(Collectors.toList());
//		}

        return ResponseVo.success(list);
    }

    /**
     * 获取预警值
     *
     * @return
     */
    @RequestMapping(value = "/warnamount", method = RequestMethod.GET)
    public ResponseVo getWarnamount() {
        return ResponseVo.success(dictService.getWarnamount());
    }

    /**
     * 获取试剂字段默认值
     *
     * @return
     */
    @RequestMapping(value = "/reagentFieldData", method = RequestMethod.GET)
    public ResponseVo getReagentFieldData() {
        return ResponseVo.success(dictService.getReagentFieldData());
    }

    /**
     * 试剂高级搜索条件字段
     *
     * @return
     */
    @RequestMapping(value = "/reagentSearchField", method = RequestMethod.GET)
    public ResponseVo getReagentSearchField(Long reagentTypeId) {
        return ResponseVo.success(dictService.getReagentSearchField(reagentTypeId));
    }

    /**
     * 获取公司
     *
     * @param isLab    是否根据实验室获取:0否，1-是
     * @param classify 分类：1-试剂，2-样品
     * @return
     */
    @RequestMapping(value = "/companyList", method = RequestMethod.GET)
    public ResponseVo getCompanyList(@RequestHeader(name = StarterConstant.TOKEN) String token,
                                     @RequestParam(required = false, defaultValue = "0") Integer isLab, Integer classify) {
        UserInfoVo urs = usersLogic.getUserByToken(token);
        List<Company> collect = companyService.getCompanyList(isLab, classify, urs.getLabId());
        return ResponseVo.success(collect);
    }

    @GetMapping("/version")
    public ResponseVo getVersionInfo() {
        ClientVersion version = clientVersionService.getVersionInfo(ClientVersionTypeEnum.ALLINONE);
        return ResponseVo.success(version);
    }

    @GetMapping("/health")
    public ResponseVo healthCheck() {
        return ResponseVo.success();
    }

    /**
     * 发送邀请链接
     *
     * @return
     */
    @GetMapping("/sendRegLink")
    public ResponseVo sendRegLink(Integer sendType, String receiver, @RequestHeader(name = StarterConstant.TOKEN) String token) {
        Assert.isTrue(sendType != null, ResultEnum.REQUEST_PARAM_LACK.getMessage());
        Assert.isTrue(StringUtils.isNotBlank(receiver), ResultEnum.REQUEST_PARAM_LACK.getMessage());
        UserInfoVo userInfo = usersLogic.getUserByToken(token);

        //用户注册校验
        if (sendType.equals(1)) {
            Users user = usersLogic.getUser(receiver);
            if (user != null) {
                boolean isHaveLab = labApplyLogic.CheckPIUser(user);
                Assert.isTrue(isHaveLab, "此用户已经是PI，无法邀请！");

                LabMember labMember = labMemberService.selectMember(userInfo.getLabId(), user.getId());
                if (labMember != null && LabMemberEnum.State.STATE_IN.getValue().equals(labMember.getState())) {
                    ResponseVo failure = ResponseVo.failure(ResultEnum.USER_EXIST_CURRENT_LAB.getMessage());
                    failure.setCode(ResultEnum.USER_EXIST_CURRENT_LAB.getCode());
                    //failure.setData(user);
                    return failure;
                }
            }

            UserInviteAudit userInviteAudit = userInviteAuditService.selectByLabIdAndMobile(userInfo.getLabId(), receiver);
            if (userInviteAudit != null) {
                if (userInviteAudit.getState().equals(UserInviteAuditStateEnum.WAIT_AUDIT.getValue()) && userInviteAudit.getInviteState().equals(UserAuditInviteStateEnum.INVITE_ING.getValue())) {
                    //待审核+邀请中
                    return ResponseVo.failure(ResultEnum.LAB_NO_PI_OR_LAB_AUDIT_WAIT_PC, "您已经邀请过此用户！", "您已经邀请过此用户！");
                }
                else if (userInviteAudit.getState().equals(UserInviteAuditStateEnum.WAIT_AUDIT.getValue()) && userInviteAudit.getInviteState().equals(UserAuditInviteStateEnum.SUBMIT_APPLY.getValue())) {
                    //待审核+提交申请
                    return ResponseVo.failure(ResultEnum.LAB_NO_PI_OR_LAB_AUDIT_WAIT_PC, "此用户已提交申请！目前正在等待审核！", "此用户已提交申请！目前正在等待审核！");
                }
                else if (userInviteAudit.getState().equals(UserInviteAuditStateEnum.WAIT_CHECK.getValue())) {
                    //待验证
                    return ResponseVo.failure(ResultEnum.LAB_NO_PI_OR_LAB_AUDIT_WAIT_PC, "此用户已提交申请，需要在邮箱中点击链接验证", "此用户已提交申请，需要在邮箱中点击链接验证");
                } else if (userInviteAudit.getState().equals(UserInviteAuditStateEnum.WAIT_PI_AUDIT.getValue())) {
                    //待PI审核
                    return ResponseVo.failure(ResultEnum.LAB_NO_PI_OR_LAB_AUDIT_WAIT_PC, "此用户已提交申请，需要PI审核成功后才可以加入实验室！", "此用户已提交申请，需要PI审核成功后才可以加入实验室！");
                }
            }
        }

        userInviteAuditLogic.addInviteAudit(userInfo, sendType, receiver);
        return ResponseVo.success("发送邀请链接成功");
    }

    /**
     * 获取学术机构邮箱后缀
     *
     * @return
     */
    @GetMapping("/getLearningEmailSuffixList")
    public ResponseVo getLearningEmailSuffixList() {
        SystemConfig emailSuffix = systemConfigService.selectByCode(SystemConfigConstant.EMAIL_SUFFIX);
        JSONArray suffixArr = JSON.parseArray(emailSuffix.getValue());
        return ResponseVo.success(suffixArr);
    }

    /**
     * 获取微信分享信息
     *
     * @return
     */
    @GetMapping("/wxShareInfo")
    public ResponseVo getWxShareInfo(@RequestHeader(name = StarterConstant.TOKEN) String token) {
        UserInfoVo userInfoVo = usersLogic.getUserByToken(token);
        SystemConfig wx_share = systemConfigService.selectByCode(SystemConfigConstant.WX_SHARE);
        JSONObject jsonObject = JSON.parseObject(wx_share.getValue());
        int userCount = 1000;//用户数
        List<Users> usersList = usersService.selectAllUserList();
        if (!CollectionUtils.isEmpty(usersList)) {
            Users users = usersList.stream().filter(p -> p.getId().equals(userInfoVo.getId())).findAny().orElse(null);
            int num = usersList.indexOf(users) + 1;
            userCount += num;
        }
        Long useDays = TimeUtil.getBetweenDays(DateUtil.stringToDate("2019-10-23", "yyyy-MM-dd").getTime(), System.currentTimeMillis());
        String title = String.format("我是LabInOne第%s位用户，使用%s天大幅提升实验效率，强烈推荐！", userCount, useDays);

        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("title", title);
        if (jsonObject != null) {
            dataMap.put("icon_url", jsonObject.getString("icon_url"));
            dataMap.put("share_url", jsonObject.getString("share_url"));
            dataMap.put("description", jsonObject.getString("description"));
        }

        return ResponseVo.success(dataMap);
    }


    /**
     * 获取二维码信息
     *
     * @return
     */
    @GetMapping("/qrcodeInfo")
    public ResponseVo getQrcodeInfo(@RequestHeader(name = StarterConstant.TOKEN) String token) {
        UserInfoVo userInfoVo = usersLogic.getUserByToken(token);
        SystemConfig qrcode = systemConfigService.selectByCode(SystemConfigConstant.QRCODE);
        JSONObject jsonObject = JSON.parseObject(qrcode.getValue());
        return ResponseVo.success(jsonObject);
    }

    /**
     * 获取客服信息
     *
     * @return
     */
    @GetMapping("/customServiceInfo")
    public ResponseVo getCustomServiceInfo() {
        SystemConfig kfInfo = systemConfigService.selectByCode(SystemConfigConstant.KF_INFO);
        JSONObject jsonObject = JSON.parseObject(kfInfo.getValue());
        return ResponseVo.success(jsonObject);
    }

    /**
     * 获取微信分享信息
     *
     * @return
     */
    @GetMapping("/testEmail")
    public ResponseVo testEmail(String realName, String email) {
        //邮件发送测试
        String sendTitle = "【LabInOne】用户邮箱验证";
        //URL url = this.getClass().getClassLoader().getSystemResource("templates/emailValidateTemp.html");
        InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("templates/emailValidateTemp.html");

        EmailSendUtil emailSender = emailService.getEmailSender();
        String sendHtml = emailSender.getEmailHtml(resourceAsStream);

        sendHtml = sendHtml.replace("{realName}", realName);
        sendHtml = sendHtml.replace("{validateUrl}", "http://www.labinone.com");
        messageLogic.sendEmail(sendTitle, sendHtml, email);

        sendTitle = "来自【张三丰】的邀请";
        resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("templates/initAccountInfoTemp.html");
        sendHtml = emailSender.getEmailHtml(resourceAsStream);

        sendHtml = sendHtml.replace("{realName}", realName);
        sendHtml = sendHtml.replace("{validateUrl}", "http://www.labinone.com");
        messageLogic.sendEmail(sendTitle, sendHtml, email);

        sendTitle = "来自【张三丰Lab】邀请注册";
        resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("templates/inviteRegTemp.html");
        sendHtml = emailSender.getEmailHtml(resourceAsStream);

        sendHtml = sendHtml.replace("{realName}", realName);
        sendHtml = sendHtml.replace("{validateUrl}", "http://www.labinone.com");
        messageLogic.sendEmail(sendTitle, sendHtml, email);

        return ResponseVo.success();
    }
    
    /**
     * 获取上传文件黑名单列表
     *
     * @return
     */
    @RequestMapping(value = "/fileBlacklist", method = RequestMethod.GET)
    public ResponseVo getFileBlacklist() {
    	SystemConfig systemConfig = systemConfigService.selectByCode("file_blacklist");
    	String value = systemConfig.getValue();
    	List<String> blacklist = null;
    	if(StringUtils.isNoneBlank(value)) {
    		blacklist = JSON.parseArray(value, String.class);
    	}
        return ResponseVo.successMap("blacklist",CollectionUtils.isEmpty(blacklist)?null:blacklist);
    }

}
